#include "mbed.h"

#include "EwPainter.h"


EwPainter::EwPainter() {
    _contextSaved = false;
}

void EwPainter::enableAlpha(bool on) {
    GUI_EnableAlpha((on ? 1 : 0));
}

ewColor_t EwPainter::getBackgroundColor() {
    return GUI_GetBkColor();
}

void EwPainter::setBackgroundColor(ewColor_t c) {
    GUI_SetBkColor(c);
}

ewColor_t EwPainter::getColor() {
    return GUI_GetColor();
}

void EwPainter::setColor(ewColor_t c) {
    GUI_SetColor(c);
}

uint8_t EwPainter::getPenSize() {
    return GUI_GetPenSize();
}

void EwPainter::setPenSize(uint8_t size) {
    GUI_SetPenSize(size);
}

void EwPainter::move(int32_t dx, int32_t dy) {
    GUI_MoveRel(dx, dy);
}

void EwPainter::moveTo(int32_t x, int32_t y) {
    GUI_MoveTo(x, y);
}

void EwPainter::clear() {
    GUI_Clear();
}

void EwPainter::clearRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
    GUI_ClearRect(x0, y0, x1, y1);
}

void EwPainter::copyRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t width, int32_t height) {
    GUI_CopyRect(x0, y0, x1, y1, width, height);
}

void EwPainter::drawHorizGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, ewColor_t c0, ewColor_t c1) {
    GUI_DrawGradientH(x0, y0, x1, y1, c0, c1);
}

void EwPainter::drawVertGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, ewColor_t c0, ewColor_t c1) {
    GUI_DrawGradientV(x0, y0, x1, y1, c0, c1);
}
void EwPainter::drawHorizRoundGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, ewColor_t c0, ewColor_t c1) {
    GUI_DrawGradientRoundedH(x0, y0, x1, y1, radius, c0, c1);
}

void EwPainter::drawVertRoundGradient(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, ewColor_t c0, ewColor_t c1) {
    GUI_DrawGradientRoundedV(x0, y0, x1, y1, radius, c0, c1);
}

void EwPainter::drawPixel(int32_t x, int32_t y) {
    GUI_DrawPixel(x, y);
}

void EwPainter::drawPoint(int32_t x, int32_t y) {
    GUI_DrawPoint(x, y);
}

void EwPainter::drawRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
    GUI_DrawRect(x0, y0, x1, y1);
}

void EwPainter::drawRect(ewRect_t *pRect) {
    GUI_DrawRectEx(pRect);
}


void EwPainter::drawRoundedFrame(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, int32_t width) {
    GUI_DrawRoundedFrame(x0, y0, x1, y1, radius, width);
}

void EwPainter::drawRoundedRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius) {
    GUI_DrawRoundedRect(x0, y0, x1, y1, radius);
}

void EwPainter::fillRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
    GUI_FillRect(x0, y0, x1, y1);
}

void EwPainter::fillRect(ewRect_t *pRect) {
    GUI_FillRectEx(pRect);
}

void EwPainter::fillRoundedRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius) {
    GUI_FillRoundedRect(x0, y0, x1, y1, radius);
}

void EwPainter::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1) {
    GUI_DrawLine(x0, y0, x1, y1);
}

void EwPainter::drawLine(int32_t dx, int32_t dy) {
    GUI_DrawLineRel(dx, dy);
}

void EwPainter::drawLineTo(int32_t x, int32_t y) {
    GUI_DrawLineTo(x, y);
}

void EwPainter::drawHorizLine(int32_t y, int32_t x0, int32_t x1) {
    GUI_DrawHLine(y, x0, x1);
}

void EwPainter::drawVertLine(int32_t x, int32_t y0, int32_t y1) {
    GUI_DrawVLine(x, y0, y1);
}

void EwPainter::drawPolyLine(ewPoint_t* pPoints, int numPoints, int32_t x, int32_t y) {
    GUI_DrawPolyLine(pPoints, numPoints, x, y);
}

ewLineStyle_t EwPainter::getLineStyle() {
    return (ewLineStyle_t) GUI_GetLineStyle();
}

ewLineStyle_t EwPainter::setLineStyle(ewLineStyle_t style) {
    return (ewLineStyle_t)GUI_SetLineStyle(style);
}

void EwPainter::drawPolygon(ewPoint_t* pPoints, int numPoints, int32_t x, int32_t y) {
    GUI_DrawPolygon(pPoints, numPoints, x, y);
}

void EwPainter::enlargePolygon(ewPoint_t* pDest, ewPoint_t* pSrc, int numPoints, int32_t len) {
    GUI_EnlargePolygon(pDest, pSrc, numPoints, len);
}

void EwPainter::magnifyPolygon(ewPoint_t* pDest, ewPoint_t* pSrc, int numPoints, int32_t mag) {
    GUI_MagnifyPolygon(pDest, pSrc, numPoints, mag);
}

void EwPainter::rotatePolygon(ewPoint_t* pDest, ewPoint_t* pSrc, int numPoints, float angle) {
    GUI_RotatePolygon(pDest, pSrc, numPoints, angle);
}

void EwPainter::fillPolygon(ewPoint_t* pPoints, int numPoints, int32_t x, int32_t y) {
    GUI_FillPolygon(pPoints, numPoints, x, y);
}

void EwPainter::drawCircle(int32_t x0, int32_t y0, int32_t radius) {
    GUI_DrawCircle(x0, y0, radius);
}

void EwPainter::fillCircle(int32_t x0, int32_t y0, int32_t radius) {
    GUI_FillCircle(x0, y0, radius);
}

void EwPainter::drawEllipse(int32_t x0, int32_t y0, int32_t rx, int32_t ry) {
    GUI_DrawEllipse(x0, y0, rx, ry);
}

void EwPainter::fillEllipse(int32_t x0, int32_t y0, int32_t rx, int32_t ry) {
    GUI_FillEllipse(x0, y0, rx, ry);
}

void EwPainter::drawArc(int32_t xCenter, int32_t yCenter, int32_t rx, int32_t ry, int32_t a0, int32_t a1) {
    GUI_DrawArc(xCenter, yCenter, rx, ry, a0, a1);
}

void EwPainter::drawGraph(int16_t* paY, int numPoints, int32_t x0, int32_t y0) {
    GUI_DrawGraph(paY, numPoints, x0, y0);
}

void EwPainter::drawPie(int32_t x0, int32_t y0, int32_t radius, int32_t a0, int32_t a1) {
    GUI_DrawPie(x0, y0, radius, a0, a1, 0);
}

void EwPainter::drawChar(uint16_t c) {
    GUI_DispChar(c);
}

void EwPainter::drawChar(uint16_t c, int32_t x, int32_t y) {
    GUI_DispCharAt(c, x, y);
}

void EwPainter::drawChars(uint16_t c, int32_t cnt) {
    GUI_DispChars(c, cnt);
}

void EwPainter::newLine() {
    GUI_DispNextLine();
}

void EwPainter::drawString(const char* s, int32_t maxLen) {
    if (maxLen <= -1) {
        GUI_DispString(s);
    }
    else {
        GUI_DispStringLen(s, maxLen);
    }
}
void EwPainter::drawString(const char* s, int32_t x, int32_t y) {
    GUI_DispStringAt(s, x, y);
}

void EwPainter::drawStringClearEOL(const char* s, int32_t x, int32_t y) {
    GUI_DispStringAtCEOL(s, x, y);
}

void EwPainter::drawStringHorizCenter(const char* s, int32_t x, int32_t y) {
    GUI_DispStringHCenterAt(s, x, y);
}

void EwPainter::drawStringRect(const char* s, ewRect_t *pRect, ewTextAlign_t align, ewWrapMode_t wrap) {
    if (wrap == WrapModeNone) {
        GUI_DispStringInRect(s, pRect, align);
    }
    else {
        GUI_DispStringInRectWrap(s, pRect, align, (GUI_WRAPMODE)wrap);
    }
}

void EwPainter::drawStringRect(const char* s, ewRect_t *pRect, ewTextAlign_t align, int32_t maxLen, ewRotation_t rotation) {

    GUI_ROTATION* ewRotation = GUI_ROTATE_0;
    switch (rotation) {
    case Rotation_0:
        break;
    case Rotation_180:
        ewRotation = GUI_ROTATE_180;
        break;
    case Rotation_CCW:
        ewRotation = GUI_ROTATE_CCW;
        break;
    case Rotation_CW:
        ewRotation = GUI_ROTATE_CW;
        break;
    }

    GUI_DispStringInRectEx(s, pRect, align, maxLen, ewRotation);
}

int32_t EwPainter::getNumWrapLines(const char* s, int32_t width, ewWrapMode_t wrap) {
    return GUI_WrapGetNumLines(s, width, (GUI_WRAPMODE)wrap);
}

ewTextMode_t EwPainter::getTextMode() {
    return (ewTextMode_t) GUI_GetTextMode();
}

void EwPainter::setTextMode(ewTextMode_t mode) {
    GUI_SetTextMode(mode);
}


void EwPainter::setTextStyle(ewTextStyle_t style) {
    GUI_SetTextStyle(style);
}

ewTextAlign_t EwPainter::getTextAlign() {
    return (ewTextAlign_t) GUI_GetTextAlign();
}

void EwPainter::setTextAlign(ewTextAlign_t align) {
    GUI_SetTextAlign(align);
}

bool EwPainter::setTextPosition(int32_t x, int32_t y) {
    return (GUI_GotoXY(x, y) == 0);
}

void EwPainter::getTextPosition(int32_t &x, int32_t &y) {
    x = GUI_GetDispPosX();
    y = GUI_GetDispPosY();
}

const ewFont_t* EwPainter::setFont(const ewFont_t* pFont) {
    return GUI_SetFont(pFont);
}

const ewFont_t* EwPainter::getFont() {
    return GUI_GetFont();
}

int32_t EwPainter::getCharWidth(uint16_t c) {
    return GUI_GetCharDistX(c);
}

int32_t EwPainter::getFontHeight() {
    return GUI_GetFontSizeY();
}

int32_t EwPainter::getFontDistY() {
    return GUI_GetFontDistY();
}

int32_t EwPainter::getLeadingBlankCols(uint16_t c) {
    return GUI_GetLeadingBlankCols(c);
}

int32_t EwPainter::getTrailingBlankCols(uint16_t c) {
    return GUI_GetTrailingBlankCols(c);
}

int32_t EwPainter::getStringWidth(const char* s) {
    return GUI_GetStringDistX(s);
}

bool EwPainter::isCharInFont(const ewFont_t* pFont, uint16_t c) {
    return (GUI_IsInFont(pFont, c) == 1);
}

void EwPainter::drawBitmap(const ewBitmap_t* pBm, int32_t x, int32_t y) {
    GUI_DrawBitmap(pBm, x, y);
}

void EwPainter::drawBitmapMagnified(const ewBitmap_t* pBm, int32_t x, int32_t y, int32_t xMul, int32_t yMul) {
    GUI_DrawBitmapMag(pBm, x, y, xMul, yMul);
}

void EwPainter::drawBitmapScaled(const ewBitmap_t* pBm, int32_t x, int32_t y, int32_t xCenter, int32_t yCenter, int32_t xMag, int32_t yMag) {
    GUI_DrawBitmapEx(pBm, x, y, xCenter, yCenter, xMag, yMag);
}

void EwPainter::drawJpeg(const void* pData, int32_t dataSize, int32_t x, int32_t y) {
    GUI_JPEG_Draw(pData, dataSize, x, y);
}

void EwPainter::drawJpegScaled(const void* pData, int32_t dataSize, int32_t x, int32_t y, int32_t num, int32_t denom) {
    GUI_JPEG_DrawScaled(pData, dataSize, x, y, num, denom);
}

void EwPainter::getJpegSize(const void* pData, int32_t dataSize, int32_t &width, int32_t &height) {
    GUI_JPEG_INFO info;
    GUI_JPEG_GetInfo(pData, dataSize, &info);

    width = info.XSize;
    height = info.YSize;
}

void EwPainter::drawGif(const void* pData, int32_t dataSize, int32_t x, int32_t y, int32_t imgIdx) {
    if (imgIdx < 0) {
        GUI_GIF_Draw(pData, dataSize, x, y);
    }
    else {
        GUI_GIF_DrawSub(pData, dataSize, x, y, imgIdx);
    }
}

void EwPainter::drawGifScaled(const void* pData, int32_t dataSize, int32_t x, int32_t y, int32_t imgIdx, int32_t num, int32_t denom) {
    GUI_GIF_DrawSubScaled(pData, dataSize, x, y, imgIdx, num, denom);
}

void EwPainter::getGifSize(const void* pData, int32_t dataSize, int32_t &width, int32_t &height) {
    width = GUI_GIF_GetXSize(pData);
    height = GUI_GIF_GetYSize(pData);
}

int32_t EwPainter::getGifNumImages(const void* pData, int32_t dataSize) {
    GUI_GIF_INFO info;
    GUI_GIF_GetInfo(pData, dataSize, &info);

    return info.NumImages;
}

void EwPainter::drawPng(const void* pData, int32_t dataSize, int32_t x, int32_t y) {
    GUI_PNG_Draw(pData, dataSize, x, y);
}

void EwPainter::getPngSize(const void* pData, int32_t dataSize, int32_t &width, int32_t &height) {
    width = GUI_PNG_GetXSize(pData, dataSize);
    height = GUI_PNG_GetYSize(pData, dataSize);;
}


void EwPainter::saveContext() {
    GUI_SaveContext_W(&_context);
    _contextSaved = true;
}

void EwPainter::restoreContext() {
    if (!_contextSaved) return;

    GUI_RestoreContext(&_context);

    _contextSaved = false;
}


